Gmsh, Meshio, Dolfin

XML is plaintext, Which makes it hard to read in parallel.
To quote the xdmf site: XDMF Model and Format - XdmfWeb

XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) or Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5[3] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored.

This means that xdmf is suitable for large files and parallel computing.

pygmsh is a convenience wrapper around the Python API of GMSH, and offers a subset of the commands in the Gmsh Python api. Historically pygmsh has had a “neater” interface than the GMSH Python api (thus its popularity). Personally, I use the GMSH Python API, as the user interface is stable, and allows me to do anything that is part of GMSH.

That said, you can combine the two (as pygmsh calls gmsh), But it might be confusing.

Yes

This writes information abou physical mesh groups that has received a tag/marker in Gmsh to a format that can be read by Dolfin/Paraview.

Meshes generated with Gmsh always has 3D coordinates. For Finite element applications, it is important to know if your mesh is 2D, or a 2D manifold in a 3D space (as gradients, normals and general vectors differ).

Yes

See Difference between meshvaluecollection and meshfunction - #2 by dokken

As Im not at a computer this script is a bit to complex to read for me (as you are not using the Gmsh API with return values, but hardcoded tags, so I cant comment on this at the moment