Since most of the answers use pre-order and level-order traversal. Here is my post-order traversal solution as an inspiration. The idea is to get the bottom left value of each subtree at each root, compare their depths and pass onto its parent.

```
private class ResultSet {
final int depth;
final int val;
ResultSet(int depth, int val) {
this.depth = depth;
this.val = val;
}
}
public int findBottomLeftValue(TreeNode root) {
return bottomLeft(root, 0).val;
}
private ResultSet bottomLeft(TreeNode root, int depth) {
if (root == null) return null;
if (root.left == null && root.right == null) return new ResultSet(depth, root.val);
else if (root.left == null) return bottomLeft(root.right, depth + 1);
else if (root.right == null) return bottomLeft(root.left, depth + 1);
else {
ResultSet left = bottomLeft(root.left, depth + 1);
ResultSet right = bottomLeft(root.right, depth + 1);
return right.depth > left.depth ? right : left;
}
}
```