How to exclude category ID from Looper in WordPress

The solution is already in your code:

 <?php foreach (get_categories( $args ) as $cat ) : ?>

<a class="categorylink" href="<?php echo get_category_link($cat->term_id); ?>"><img src="<?php echo z_taxonomy_image_url($cat->term_id); ?>" />

More specifically:

 <?php foreach (get_categories( $args ) as $cat ) : ?>

...get_category_link($cat->term_id)...

That term_id is the ID of the category, so just test if it matches one of your undesired IDs and continue; to skip to the next one.


However, there is an unrelated but super critical mistake in your code. Shortcodes do not echo/output directly. They need to return their output in a string. This shortcode will break a lot of things, and will appear in the wrong place.

Remember:

function brokenshortcode() {
    ?><p>I am an awful shortcode that breaks lots of things</p><?php
}
add_shortcode( 'broken', 'brokenshortcode' );
function niceshortcode() : string {
    return '<p>I am a good well behaved shortcode</p>';
}
add_shortcode( 'nice', 'niceshortcode' );

You can enforce this by type hinting the function like this:

function my_categories_shortcode() : string {

Now the function will cause a PHP fatal if you make this mistake