newData is a pointer to data which means it points to the exact same place in memory. The same memory can't have 2 different values - otherwise you could double the memory in your computer per software (which would be nice...). So you need to create a copy first:
newData = new char[60][60]; memcpy(newData, data, sizeof data);
The next thing is - the array you pass as parameter is a real copy. So anything changed inside the function won't be returned.
If you want to return it then pass a reference to an array like: func(char (&data)[60][60]). Which can call then with func(data) or func(*newData). I had to look-up reference to array syntax as well btw ;-) (hope that works with 2-dimensional arrays, I did not compile...)
Personally I find it mostly easier to work with one-dimensional arrays and doing the access calculation myself (y*width+x). Especially easier once you want the size to be dynamic. (and it's not slower than 2-dimensional arrays as the compiler will have to do the y*width+x to acccess elements as well)