What is the most convenient way to apply boundary conditions in a FVM code? (i.e. how commercial codes like Ansys or Fluent do this?)
Until recently I used ghost cells to set boundary conditions in my program, but as I understand this is an explicit method and could lead to restrictions on the timestep. I am trying to simulate mostly diffusion driven flows near the onset of convective instability with concentration variation and thermodiffusion, so I would like to have the timestep as large as possible. Is there an implicit variant of the ghost cell method? If no, could you suggest what is the best way to proceed with the boundary conditions?

This actually isn't specific to FVM, but the most fundamental decision to make is whether to remove boundary dofs which are being enforced strongly. People really don't agree about this, removing the dofs makes the system slightly smaller and does not perturb the spectrum like penalty methods (which produce huge eigenvalues) and zeroing a row (which introduces additional asymmetry, perturbing eigenvalues). To leave the dofs in without messing up the spectrum, you can also zero the column. In function evaluation, zeroing the column is equivalent to correcting the boundary values before computing fluxes. In Jacobian assembly, you should remove these columns at the local level (doing columnwise operations on a global matrix in compressed row form is really expensive).

Using ghost cells is fine during function evaluation. When the value in the ghost cell is filled in by extrapolation, it is equal to a linear combination of values in nearby cells. When assembling the Jacobian, you can apply this linear combination at the local level.