It's explained in the Tailscale article I linked above. With both MikroTik routers being behind NAT, and you configure the WireGuard interface on router 1 to use UDP port p1, on router 2 to use UDP port p2. Router 1 sees the IPv4 address on its WAN interface as a1.b1.c1.d1, router 2 see its address as a2.b2.c2.d2.
It's obvious that on router 1, configuring the remote WG peer as having endpoint-address=a2.b2.c2.d2 and endpoint-port=p2 will not work. Same with configuring the WG peer on router 2 with endpoint-address=a1.b1.c1.d1 and endpoint-port=p1. Because when router 1 sends out WG packet with the source a1.b1.c1.d1:p1, the NAT in front of it (for example the ISP's CGNAT) will transform the source into w1.x1.y1.z1:q1. Similarly, with router 2, the source of the packets is changed from a2.b2.c2.d2:p2 to w2.x2.y2.z2:q2.
The ISP NAT on the router 1 side will only translate incoming packets with destination w1.x1.y1.z1:q1 (as return packets) back to a1.b1.c1.d1:p1, and the ISP NAT on the router 2 side will only translate incoming packets with destination w2.x2.y2.z2:q2 back to a2.b2.c2.d2:p2.
To be able to establish a WG handshake between the two routers, At least, either router 1 musts know what w2.x2.y2.z2 and q2 are, or router 2 musts know what w1.x1.y1.z1 and q1 are.
Knowing what w1.x1.y1.z1 or w2.x2.y2.z2 are is easy, you can even do it manually with websites like https://ifconfig.me/ip. The challenge is to figure out the correct value for q1 and/or q2!
It's easier if one or both NAT sides use Endpoint-Independent Mapping. For example, let's say that the router 1 side ISP implement EIM, then within some time period after router 1 sends out an UDP packet with source a1.b1.c1.d1:p1 to the internet and the ISP NATs the source to w1.x1.y1.z1:q1, every other UDP packets that router 1 sends out with a1.b1.c1.d1:p1 as source, regardless of destination (doesn't have to be the same destination as the previous packet) will also have the source translated to the same w1.x1.y1.z1:q1. The value q1 is the same, independent from the destination (hence Endpoint-Independent Mapping).
In that case, it's trivial to figure out what q1 is if we have a helper server with public accessible IP address (for example a STUN server). Router 1 sends UDP packet with source a1.b1.c1.d1:p1 to that helper service, and the server can see the value for q1 (and of course w1.x1.y1.z1 too). Router 2 can then set the endpoint of the WG peer to w1.x1.y1.z1:q1 and make handshake attempts. Due to using EIM, the NAT on the router 1 ISP side will translate the incoming packets with destination w1.x1.y1.z1:q1 to a1.b1.c1.d1:p1 and the packets will arrive at the WG port on router 1.
Even if we don't have a 3rd party public reachable STUN server, a trick can be employed where the two router sides make hundreds of attempts with different port numbers toward the other router. As explained with the birthday paradox, a few hundreds of tries are enough to have a 50% matching chance, and with 1000 probes the chance raises to 98%.
The big problem is when neither of the side have EIM NAT, only Endpoint-Dependent Mapping. This is a Symmetric NAT situation. The value of the mapped port q1 for example, not only depends on the source a1.b1.c1.d1:p1, but also on the destination of the UDP packet. Different destinations produce different q1 for the same p1.
In that case, the trick with the helper STUN server no longer works. Because the port q1 that the STUN server sees might be different from the mapped port number that router 1's ISP choose when router 1 tries to connect to router 2 (two different destinations).
The random probe method also becomes much more difficult, because the number of possibilities has squared (65K * 65K), according to the article, each side need to send 170K probes for a 99.9% success rate. Which might not even work, the ISPs might see the flooding as hacking attempts and block everything. Or, most probably, the ISP NAT mapping table has limited entries and will recycle the ports, which means a match might never be found, even with millions of tries. Also. you'll have to figure out how to do that probing with RouterOS script, or write programs that do the probing and run them on both sides on hosts with DMZ enabled.
That's why usually in case of Symmetric NAT after some unsuccessful probing, a 3rd party relay service will be used instead (like the MikroTik relay with BTH).
Conclusion: It's realistically doable without the help from public helper server only if the NAT on at least one side uses Endpoint-Independent Mapping.
Other note: If you are an ISP and use MikroTik devices, then don't forget that the default SRCNAT in RouterOS is not Endpoint-Independent. If you are ISP and use the normal masquerade or src-nat action then your customers might have issues caused by "Symmetric NAT". The NAT chains have a special action for endpoint-independent-nat that works only for UDP: NAT | RouterOS Manual. And normally you'll have rules for both directions, for example:
/ip firewall nat
add action=endpoint-independent-nat chain=srcnat \
out-interface-list=WAN protocol=udp randomise-ports=no
add action=endpoint-independent-nat chain=dstnat \
in-interface-list=WAN protocol=udp randomise-ports=no
This is not important if the router is only your home router.