There is an algorithm for computing the integral closure of a commutative, noetherian, reduced ring originally due to Grauert and Remmert and popularized by Theo de Jong in his paper *An Algorithm for Computing the Integral Closure*: https://arxiv.org/pdf/alg-geom/9704017.pdf. The rough idea is that a commutative, noetherian, reduced ring $R$ is normal, i.e. integrally closed in its field of fractions, if and only if $R=\text{Hom}_R(I,I)$ for some sufficiently nice ideal $I$.

The conditions on the "sufficiently nice" ideal are mild: 1. the ideal $I$ must contain a non-zero divisor, 2. the ideal $I$ must contain the non-normal locus $NNL:=\{p\in\text{Spec}(R):R_p\text{ is not normal}\}$ of the ring $R$, and 3. it must be the case that $\text{Hom}_R(I,I)=\text{Hom}_R(I,R)\cap\overline{R}$, where $\overline{R}$ denotes the integral closure of $R$.

If all of those hypotheses are satisfied, $R$ is normal if and only if $R=\text{Hom}_R(I,I)$. Theo de Jong's paper discusses how $\text{Hom}_R(I,I)$ can be given a ring structure (this is due to Fabrizio Catanese), which allows for easy comparison of the ring $R$ with the ring arising from $\text{Hom}_R(I,I)$.

In fact, this is the algorithm upon which the integralClosure() in Macaulay2 is based! So, we find an ideal satisfying the hypotheses above (often, the radical of the Jacobian ideal of the variety) and check the equality $R=\text{Hom}_R(I,I)$. If it's not an equality, there are some elements of $\text{Hom}_R(I,I)$ not in $R$. Toss them in and then check $R=\text{Hom}_R(I,I)$ again. Continue this process until equality holds. This process must terminate due to the finiteness of integral closure for excellent rings.

I wrote a little about this here: https://www.overleaf.com/read/vxndphzqkqvf