There's no tail recursion in that function. For tail recursion to apply, you generally need to have nothing appearing after the recursive call (the call to "back()"). In this case, a character is printed out after the recursive call, which means that the character value must be retained through the recursive call, which breaks tail recursion (or makes tail-call optimization impossible). If someone claimed that this code uses tail recursion, then that person is wrong.
The easiest way to tell if something can be tail-call optimized is to see if you can manually translate the function into an iterative one (instead of recursive) and see if you can do it without auxiliary memory. In this case, there is no way to do that iteratively without having O(N) memory. For example, one way to do this iteratively is to store all the characters into an array and then traverse that array in reverse to print out the characters, which implies that you need an array of N characters to make this work. The recursive form you have there does the same thing, except that the characters are stored in function-call stack-frames instead of in a simple array, which is just inefficient and bad style (and unsafe, by the way).