I use Blender and MeshLab along with some custom experimental tools based on numpy, etc. The easiest way to results is probably using MeshLab.
Import PLY
Filters → Sampling → Poisson Disk Sampling, Base Mesh Subsampling selected [1]
Filters → Normals, Curvatures and Orientation → Compute Normals for Point Sets [2]
Filters → Remeshing, Simplification and Reconstruction → Surface Reconstruction: Poisson [3]
** Bonus round
Render → Render Mode → Flat [4]
Export
1 This step reduces stray points. Put in a really simple way, imagine a box of cubes (like a 3D grid) placed over the model. The sampling only takes one point within the cube (grid) and removes the rest. In short, this reduces noise.
2 Helps in building geometry. Put in a really simple way, this tells the next step which direction the generated faces should be facing. Without this step, the next step doesn’t really know whether to build triangles (faces) pointing up, down, backwards, etc and what points to attempt to build them out of.
3 Again leveraging Poisson, this step “guesses” what the geometry should approximately look like and then builds faces with the normal data collected in step 2.
4 This step is let you see what your final mesh will look like. If it’s missing then repeat the process with different values. At this point you can use other MeshLab tools to correct the mesh, fill in missing faces, etc.
Export!
** Bonus round steps are for when you feel comfortable with the basic workflow. The next step is to import multiple point clouds including point clouds generated from different angles (ie: the object laying on its side) and align them. Then go through roughly the same basic workflow to get even better geometry. Even with the bonus round steps, my Tux toy is still roughly 30% modeled in Blender, 10% corrected and tweaked in MeshLab and 60% data from Horus/Ciclop.
If anyone knows an easier way, let me know! I have a collection of automated tools, but they either produce blobs or kind of busted geometry.