There are Three ways of doing this.
The first, which works over the Internet, is to have a third server, a listing server, with a known DNS name/port, and have each server register itself with the listing server. The listing server can then do NAT introduction / punch-through as appropriate.
The second, which works only on a local network, is to use UDP broadcast on a known port. Typically, an available server will send a broadcast "I'm here" every 10 second or so. A client that wants to find a game, will send a "who's there" broadcast, which will cause the servers to immediately respond with their "I'm here" messages, to speed up discovery. (You don't want to send "I'm here" every second, or even more often, because that generates a lot of pointless network traffic.)
The third is to make each client find out its own network address (which there is no good portable way of doing, so platform specifics are needed) and then probe the entire subnet, trying to connect to a known port on each address in the subnet, and for the nodes that respond, send some kind of packet that the servers will send a known response to. I recommend against this method, as some networks have probing defense systems in place that will isolate the node trying to do the probe, plus it's slower to determine which nodes don't actually have servers, because of time-outs (even if you can run probes in parallel.)