First you'll need a lookup structure to look up vertices you've processed so far. This could be, for example, a dictionary keyed on the position of your vertices, or an octree/k-d tree/etc. Each entry will hold the updated index of the de-duplicated vertex at that position.
(If you're using this for display meshes, you'll want to count vertices with different normals/UVs as distinct, but if I recall correctly you're working on collision meshes so we can ignore this detail and treat vertices as pure positions)
Next you'll need a re-indexing list the same size as your initial list of vertex positions. This will hold the new index of each vertex after de-duplication.
Initialize a vertex count to zero. Iterate over your list of vertices, checking to see if each position (or one within a small rounding tolerance) is already in your lookup collection.
If there's no vertex recorded yet at that point, set the current vertex's new index to your current vertex count, and increment that count. Write this vertex and its new index into your lookup structure.
If you already have a vertex recorded at that point, set the current vertex's index to that recorded index and do not increment the vertex count.
Either way, write the new index you've chosen for this vertex into the re-indexing list.
At the end, or as you go, you can build your new vertex list, using only the first vertex with each new index.
Then you need to update your index list. For each entry in the list, replace it with the corresponding new index looked from your re-indexing list. ie. indices[i] = reindex[indices[i]];
Lastly, check to see whether any triangles have become degenerate (two or three indices all pointing to the same vertex) - if so, you can delete that whole triangle. (Swapping 3 indices from the end of the list, or moving the rest of the indices back 3 spaces to fill the gap)