For starters the function printArray declared like
void printArray(int **A, int m, int n);
does not make sense because the pointer A is not used within the function.
Moreover the parameter has the type int ** while the passed argument in this call
printArray(arr, 3, 3);
has the type int ( * )[3].
That is the pointer types are not compatible and as a result the compiler issues an error.
And there is no overloaded operator << for the incomplete type void that is the return type of your function.
To output any two-dimensional array (for example with elements of the type int though the element type also could be a type template parameter) you could write a template function the following way
template <size_t M, size_t N>
std::ostream & printArray( const int ( &a )[M][N], std::ostream &os = std::cout )
{
    for ( const auto &row : a )
    {
        for ( const auto &item : row )
        {
            os << item << ' ';
        }
        os << '\n';
    }
    return os;
}
And the function can be called like
printArray( arr ) << '\n';
Here is a demonstrative program.
#include <iostream>
template <size_t M, size_t N>
std::ostream & printArray( const int ( &a )[M][N], std::ostream &os = std::cout )
{
    for ( const auto &row : a )
    {
        for ( const auto &item : row )
        {
            os << item << ' ';
        }
        os << '\n';
    }
    return os;
}
int main() 
{
    int arr[3][3] = 
    {
        {1, 2, 3}, 
        {4, 5, 6}, 
        {7, 8, 9}
    };
    
    printArray( arr ) << '\n';
    
    return 0;
}
Its output is
1 2 3 
4 5 6 
7 8 9 
Otherwise without using a template you can declare and define the function the following way as it is shown in the demonstrative program below.
#include <iostream>
const size_t N = 3;
std::ostream & printArray( const int a[][N], size_t m, std::ostream &os = std::cout )
{
    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < N; j++ )
        {
            os << a[i][j] << ' ';
        }
        os << '\n';
    }
    return os;
}
int main() 
{
    int arr[][N] = 
    {
        {1, 2, 3}, 
        {4, 5, 6}, 
        {7, 8, 9}
    };
    
    const size_t M = sizeof( arr ) / sizeof( *arr );
    
    printArray( arr, M ) << '\n';
    
    return 0;
}
Again the program output is
1 2 3 
4 5 6 
7 8 9
Alternatively the function can be defined also the following way using the range-based for loop as the inner loop.
std::ostream & printArray( const int a[][N], size_t m, std::ostream &os = std::cout )
{
    for ( size_t i = 0; i < m; i++ )
    {
        for ( const auto &item : a[i] )
        {
            os << item << ' ';
        }
        os << '\n';
    }
    return os;
}