What you are seeing is the intended behaviour. It is actually caused by the definitions in the IANA Time Zone Database, not because tzinfo is jumping through linked zones.
The Country#zones method returns data from one of either the zone1970.tab or zone.tab files in the IANA Time Zone Database. zone.tab was deprecated in 2014 and replaced by zone1970.tab.
The zone1970.tab file was introduced as a simplification to the database. It only lists distinct non-linked time zones that have differences since 1970. For Croatia, this means that the correct time zone as defined by the IANA Time Zone Database maintainers in zone1970.tabisEurope/Belgrade (even though Belgrade is in Serbia).
The zone.tab file does still list the linked zone Europe/Zagreb as the time zone for Croatia.
The tzinfo-data gem includes just the data from zone1970.tab. When using your system time zone data instead of tzinfo-data, tzinfo will try and use the zone1970.tab file if it exists and will fallback to zone.tab.
I suspect that your system doesn't include the newer zone1970.tab file. When you're not using tzinfo-data, tzinfo is having to fall back to zone.tab and you see Europe/Zagreb instead of Europe/Belgrade.
The intention of the IANA Time Zone Database coordinator appears to be to stop distributing zone.tab at some point. It is therefore not really sensible to include a way of accessing the zone.tab data through tzinfo-data.
When using tzinfo-data, it is possible to query the list of zones that link to a particular zone. For example, the following would return you all the zones that link to Europe/Belgrade:
However, you would need to use a separate source of data to determine which country the identifiers of the returned zones relate to.
It sounds like you are having users select a time zone by country and then zone identifier. If this is the case then, for countries that only have a single time zone (like Croatia), I'd suggest not showing a list of zone identifiers and automatically selecting the only available option.