Avoid duplicate post from same Taxonomy

I see two ways to go about it, both quite similar.

A) You can collect IDs of displayed posts in an array and then exclude those with post__not_in query parameter like so:

$years_loop = get_terms(
    array(
        'taxonomy'  => 'works_year',
        'orderby'   => 'slug',
        'order'     => 'DESC',
        )
);

// array for displayed posts, we will update it with every loop
$displayed = [];

foreach($years_loop as $year_loop_slug) :
    $args = array(
        'post_type'       => 'works',
        'posts_per_page'  => -1,
        'post__not_in'    => array_unique( $displayed ),
        'tax_query'       => array(
            array(
                'taxonomy'  => 'works_year',
                'field'     => 'slug',
                'terms'     => array( $year_loop_slug->slug ),
                'operator'  => 'IN',
            )
        ),
    );
    $loop = new WP_Query($args);
    while ($loop->have_posts()) : $loop->the_post();

        // update array with currently displayed post ID
        $displayed[] = get_the_ID();

        //your output

    endwhile;
endforeach;

B) If you want to avoid using post__not_in parameter, which can have bad impact on your site’s performance, you can check for the duplicates inside your loops:

$years_loop = get_terms(
    array(
        'taxonomy'  => 'works_year',
        'orderby'   => 'slug',
        'order'     => 'DESC',
        )
);

// array for displayed posts, we will update it with every loop
$displayed = [];

foreach($years_loop as $year_loop_slug) :
    $args = array(
        'post_type'       => 'works',
        'posts_per_page'  => -1,
        'tax_query'       => array(
            array(
                'taxonomy'  => 'works_year',
                'field'     => 'slug',
                'terms'     => array( $year_loop_slug->slug ),
                'operator'  => 'IN',
            )
        ),
    );

    $loop = new WP_Query($args);
    while ($loop->have_posts()) : $loop->the_post();
        // if the current post was already displayed, move on to the next iteration of this loop
        if ( in_array( get_the_ID(), $displayed ) ){
            continue;
        }
        // update array with currently displayed post ID
        $displayed[] = get_the_ID();

        //your output

    endwhile;
endforeach;

Code not tested, but you get the idea.