get_term_link doesn’t work

I do not know how ACF works or how its data is stored, but in general, I would just use usort() to sort the returned array of terms via the ACF value of cognome_nome. Note that array_push is a bit expensive to use, so try to avoid that 😉

As I stated in comments, your code does not make much sense to me. You have two separate foreach loops, which is fine, but you are trying to use the value of the first foreach loop’s value ($term) in the second one, which will not work. In a foreach loop, the value of the last key remains outside/after the foreach loop, which means that $term will always be set to the last term. Because of this, and because you use $term in your second foreach loop as is, all values will be set to the last term of your $terms object. That is exactly what you are seeing.

In general, this is how I would tackle this issue

$terms = get_terms( 'authors', $args );
/**
 * Remember the usort bug. Use @usort to cut the bug's wings and feet ;-)
 */
@usort( $terms, function ( $a, $b )
{
    /**
     * Get our ACF Data
     * Just make sure that my logic is correct here and that you actually get data from get_field
     */
    $array_a = get_field( 'cognome_nome', $a );
    $array_b = get_field( 'cognome_nome', $b );

    if ( $array_a ) {
        $sort_a = $array_a;
    } else {
        $sort_a="zzz"; //Kind of fall back to add posts without field last
    }

    if ( $array_b ) {
        $sort_b = $array_b;
    } else {
        $sort_b = 'zzz'; //Kind of fall back to add posts without field last
    }

    // Sort by these ACF data
    return strcasecmp ( $sort_a, $sort_b );
});

This will take care of sorting. You can just then loop through your terms normally and output them as you would normally do