The difference is that reproject changes the geometry coordinates.  

----  

Let me start with a Point layer, with one feature, wich geometry is a point located in _latitude = 1°_, _longitude = 2°_.  

The geometry WKT is `POINT ( 1 2 )` and the layer is defined with CRS `EPSG:4326`.  

And I have a custom projected CRS which map those coordinates to _x = 2000m_, _y = 1000m_.  

If I reproject the layer to my custom CRS, the new geometry WKT will be `POINT (2000 1000)`, and the new layer will be defined with my custom CRS (e.g, `CUSTOM:100001`).  

----  

If I assign my custom CRS to the source layer without reproject it, the geometry WKT of the feature will remain `POINT ( 1 2 )`, but the layer will be defined in `CUSTOM:100001` CRS.  

And in that CRS, _x = 1m_, _y = 2m_ represent a point far away from my source point.  

----  

In QGIS 3, the project CRS is the QGIS 2 _on-the-fly_ reprojection feature.  

If the project has a CRS defined, all the layers will be reprojected on-the-fly to that CRS before show them in the map.  

Yo can set _No projection_ for the project CRS in its properties, and the layers will be shown in their own CRS.  

In that case, both geometries `POINT ( 1 2 )` will be shown aligned, altought they are located in different places of the Earth. And `POINT ( 2000 1000 )` geometry will be shown far away from the source point, altought they are the same point but defined in different CRS.  

----  

_Save layer as_, when the target CRS is not the same as the source one, implies a _Reprojection_.  

_Assign_ and _Define_ I think is the same, change the layer CRS without change the geometry coordinates.