Construct KD-Tree in Java
List.subList(low, high)


Is probably the easiest approach to take to the list management without requiring the copying of a lot of nodes.  It does make a lot of Lists though, which are very short lived.  This should be fine.  If you really needed to keep things under control, then you would replace the sublist implementation with one that uses Arrays.sort(a[], low, high, Comparator)

Reviewing the code as is:

root.leftChild = buildKDTree(left, !depth);
depth = !depth;
root.rightChild = buildKDTree(right, !depth);


This looks to me like a bug - I would expect each layer of the tree to be sorted in the same direction, so flipping the bit doesn't make sense.  Instead

root.leftChild = buildKDTree(left, !depth);
root.rightChild = buildKDTree(right, !depth);


I don't like using the boolean to control the direction of the insert -- the variable is answering a question about direction, not logical truth.  An enum would be a more readable fit

private enum SORT_DIRECTION {
    X_SORT, Y_SORT;
}


Alternatively, it might be clearer to track how deep you are in the tree, and choose the direction of the sort based on the depth.  In that case, depth would be an int, and you would use something like a modulus operation to choose which way you want the comparators to go.

Comparator&lt;Node&gt; order = Node.xComparator;

if(0 == (depth % 2){
    order = Node.yComparator;
    Collections.sort(list, Node.xComparator);
}
Arrays.sort(nodes, low, high, order);


Or better, explicitly spell out what you are doing

Comparator order = getOrderForDepth(Node, depth);
   Arrays.sort(nodes, low, high, order);

When dealing with recursion, my usual recommendation is to have a different function set up your pre conditions, and return the root.

Node buildKDTree(List list) {
       int depth = 0;
       return buildKDTree(list, depth);
   }

Finally, when implementing something recursively, make sure that you have a clear and obvious terminating condition (in other words, you need to handle the case where there are no more sub trees).  In this case, it's probably easiest to manage if the buildKDTree method handles an empty List.