<p>Using CuraEngine with my Ender 3, I'm getting what I'd call inconsistent inner and outer dimensions - for example, a nominally 3&nbsp;mm peg is significantly larger than a 3&nbsp;mm hole, and it takes dimensions something like 2.9&nbsp;mm for the peg and 3.1&nbsp;mm for the hole to get them to fit. Is this level of error normal? Is it caused by overextrusion, or does CuraEngine run its paths along the curve of the slice rather than offset by approximately half the nozzle width inside the sliced region? The magnitude of the error being almost exactly 0.2&nbsp;mm, which is half of the 0.4&nbsp;mm nozzle diameter, makes me wonder if it's the latter.</p>

Filament expands slightly as it is extruded. Also, the width of the extrusion depends on the volume of plastic extruded (not the nozzle size), as well as the amount that it is "squidged" down. Some slicers (e.g. Simplify3D) allow you to specify the width of the extrusion that you desire, but I'm not sure if Cura does this. You can fine tune the width of extrusions by adjusting the flow rate. Note that apertures get larger as nozzles wear out, but this should not affect the width of the extrusion very much since the determining factor is volumetric flow rate.
I would say that if you are getting a dimensional accuracy of +/- 0.1mm, you are doing pretty well. If you want to improve on this, you will need to calibrate your extruder and also monitor closely the average diameter of the filament that you are using. I have included a link to an external article, since doing this is beyond the scope of my answer. However, I doubt if it is possible to get push-fit accuracy with FDM printing without fudging the dimensions of the objects that you want to print.
3D Hubs: How to calibrate, tune and fine tune your printer and filament