Yes the most concise solution is recursion.
https://discuss.leetcode.com/topic/66165/very-concise-c-solution-for-general-binary-tree-not-only-bst
Here is my non-recursive solution - all cases should be covered.
class Solution { public: TreeNode* deleteNode(TreeNode* root, int key) { if(!root) return nullptr; bool bIsRoot = root->val == key; // 1. Find it TreeNode *p = root, *pp = nullptr; while(p && p->val != key) { if(p->val == key) break; pp = p; if(p->val < key) p = p->right; else p = p->left; } if(!p) return root; // not found bool isLeft = pp && pp->left == p; // 2. Delete it if(!p->left && !p->right) // leaf { if(bIsRoot) return nullptr; if (isLeft) pp->left = nullptr; else pp->right = nullptr; return root; } else if(!p->left && p->right) // only right { if(bIsRoot) return root->right; if(isLeft) pp->left = p->right; else pp->right = p->right; return root; } else if(p->left && !p->right) { if(bIsRoot) return root->left; if(isLeft) pp->left = p->left; else pp->right = p->left; return root; } else // { TreeNode *q = p->right; while(q->left) q = q->left; q->left = p->left; if(bIsRoot) { return root->right; } else { if(isLeft) pp->left = p->right; else pp->right = p->right; return root; } } return nullptr; } };