Merge Sort Implementation: Space Usage
Is the above code wasting space?


Yes. As @cHao pointed out in a comment, you are using \$O(N log N)\$ space. You can do mergesort in \$O(N)\$ space.


  Is there a better implementation?


Yes. The biggest problem wrt both time and space efficiency is that you are unnecessarily allocating and copying auxiliary arrays.

You can instead create 1 auxiliary array and pass the same array around together with the interval to be sorted, or merged.

Your methods would look like these, some implementation left exercise :

public static void mergeSort(int[] arr) { 
    mergeSortBetween(arr, new int[arr.length], 0, arr.length -1);
}

private static void mergeSortBetween(int[] arr, int[] aux, 
    int startIndex, int endIndex) {
    if (...) {
        return;
    }
    //...
    mergeSortBetween(arr, aux, startIndexLeft, endIndexLeft);
    mergeSortBetween(arr, aux, startIndexRight, endIndexRight);
    merge(arr, aux, 
        startIndexLeft, endIndexLeft, 
        startIndexRight, endIndexRight);
}

private static void mergeBetween(int[] arr, int[] aux, 
    int startIndexLeft, int endIndexLeft, 
    int startIndexRight, int endIndexRight) {
    // only need to merge consecutive chunks
    assert startIndexRight = endIndexLeft + 1;
    //merge into aux
    while (currentLeft &lt; startIndexLeft &amp;&amp; currentRight &lt; endIndexRight) {
        if (...)
            aux[...] = arr[...]
        else 
            aux[...] = arr[...]
    }
    while (currentLeft &lt; endIndexLeft) {
        aux[...] = arr[...]
    }
    while (currentRight &lt; endIndexRight) {
        aux[...] = arr[...]
    }

    //copy merged values back into arr
    System.arraycopy(aux, ..., arr, ..., ...);
}