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